<template>
  <div class="common-table">
    <a-table
      :columns="columns"
      :data-source="dataSource"
      :loading="loading"
      :pagination="paginationConfig"
      :row-key="rowKey"
      :row-selection="rowSelection"
      :scroll="scroll"
      v-bind="$attrs"
      @change="handleTableChange"
    >
      <!-- 动态插槽 -->
      <template
        v-for="column in columns"
        :key="column.key || column.dataIndex"
        #[`bodyCell`]="{ column: col, text, record, index }"
      >
        <template v-if="col.dataIndex === column.dataIndex || col.key === column.key">
          <!-- 使用自定义渲染函数 -->
          <template v-if="column.customRender">
            <component
              :is="renderCell(column.customRender, { text, record, index })"
            />
          </template>

          <!-- 使用插槽 -->
          <slot
            v-else-if="column.slots?.customRender"
            :name="column.slots.customRender"
            :text="text"
            :record="record"
            :index="index"
          />

          <!-- 默认渲染 -->
          <template v-else>
            {{ text }}
          </template>
        </template>
      </template>

      <!-- 空数据提示 -->
      <template #emptyText>
        <a-empty :description="emptyText" />
      </template>
    </a-table>
  </div>
</template>

<script setup lang="ts">
import { computed, h } from 'vue'
import type { TableColumnConfig, TableRowSelection, PaginationConfig } from '@/types'
import type { TableProps } from 'ant-design-vue'

/**
 * 组件 Props
 */
export interface CommonTableProps {
  columns: TableColumnConfig[]
  dataSource: any[]
  loading?: boolean
  pagination?: PaginationConfig | false
  rowKey?: string | ((record: any) => string)
  rowSelection?: TableRowSelection
  scroll?: { x?: number | string; y?: number | string }
  emptyText?: string
}

const props = withDefaults(defineProps<CommonTableProps>(), {
  columns: () => [],
  dataSource: () => [],
  loading: false,
  pagination: () => ({
    current: 1,
    pageSize: 10,
    total: 0,
    showSizeChanger: true,
    showQuickJumper: true,
    showTotal: (total: number) => `共 ${total} 条`,
  }),
  rowKey: 'id',
  emptyText: '暂无数据',
})

/**
 * 组件 Emits
 */
const emit = defineEmits<{
  change: [pagination: any, filters: any, sorter: any]
  refresh: []
}>()

/**
 * 分页配置
 */
const paginationConfig = computed(() => {
  if (props.pagination === false) {
    return false
  }

  return {
    ...props.pagination,
    showTotal: (total: number) => `共 ${total} 条`,
  }
})

/**
 * 表格变化回调
 */
function handleTableChange(
  pagination: any,
  filters: any,
  sorter: any
) {
  emit('change', pagination, filters, sorter)
}

/**
 * 渲染自定义单元格
 */
function renderCell(
  customRender: (params: { text: any; record: any; index: number }) => any,
  params: { text: any; record: any; index: number }
) {
  const result = customRender(params)

  // 如果返回的是字符串或数字，直接返回文本节点
  if (typeof result === 'string' || typeof result === 'number') {
    return h('span', result)
  }

  // 如果返回的是 VNode，直接返回
  return result
}

/**
 * 刷新表格
 */
function refresh() {
  emit('refresh')
}

/**
 * 暴露方法给父组件
 */
defineExpose({
  refresh,
})
</script>

<style scoped lang="less">
.common-table {
  :deep(.ant-table) {
    background-color: #fff;
  }

  :deep(.ant-table-thead > tr > th) {
    background-color: #fafafa;
    font-weight: 600;
  }

  :deep(.ant-table-tbody > tr:hover > td) {
    background-color: #f5f5f5;
  }

  :deep(.ant-pagination) {
    margin: 16px 0;
  }
}
</style>
